﻿using System.Drawing;
using System.Drawing.Drawing2D;

namespace CloudShot.Utils.Drawings
{
  public static class ShadowsGraphicsExtensions
  {
    public static void DrawFuzzyPath(this Graphics graphics, GraphicsPath gfxPath, Color outlineColor, int distance = 1, byte alpha = 192, int shadowWidth = 4, int opaqueWidth = 2)
    {
      SmoothingMode oldSoothingMode = graphics.SmoothingMode;
      graphics.SmoothingMode = SmoothingMode.AntiAlias;

      // Draw the shadow.
      graphics.TranslateTransform(distance, distance);
      graphics.DrawPathWithFuzzyLine(gfxPath, Color.FromArgb(53, 53, 53), alpha, shadowWidth, opaqueWidth);
      graphics.ResetTransform();

      //// обводка фигуры
      //using (var thickPen = new Pen(Color.FromArgb(80, outlineColor), 3))
      //{
      //  graphics.DrawPath(thickPen, gfxPath);
      //}

      graphics.SmoothingMode = oldSoothingMode;
    }

    public static void DrawPathWithFuzzyLine(this Graphics gr, GraphicsPath path, Color baseColor, int maxOpacity, int width, int opaqueWidth)
    {
      int numSteps = width - opaqueWidth + 1; // Number of pens we will use.
      float delta = (float)maxOpacity / numSteps / numSteps; // Change in alpha between pens.
      float alpha = delta; // Initial alpha.

      for (int thickness = width; thickness >= opaqueWidth; thickness--)
      {
        Color color = Color.FromArgb((int)alpha, baseColor.R, baseColor.G, baseColor.B);

        using (var pen = new Pen(color, thickness))
        {
          //var bigArrow = new AdjustableArrowCap(5, 5);

          //pen.CustomStartCap = bigArrow;
          //pen.CustomEndCap = bigArrow;

          pen.EndCap = LineCap.Round;
          pen.StartCap = LineCap.Round;
          gr.DrawPath(pen, path);
        }
        alpha += delta;
      }
    }

    //experimental
    public static void DrawPathWithFuzzyLine(this Graphics gr, GraphicsPath path, Pen pen, Color baseColor, int maxOpacity, int width, int opaqueWidth)
    {
      int numSteps = width - opaqueWidth + 1; // Number of pens we will use.
      float delta = (float)maxOpacity / numSteps / numSteps; // Change in alpha between pens.
      float alpha = delta; // Initial alpha.

      gr.TranslateTransform(1, 1);

      Pen penCopy = (Pen)pen.Clone();

      for (int thickness = width; thickness >= opaqueWidth; thickness--)
      {
        Color color = Color.FromArgb((int)alpha, baseColor.R, baseColor.G, baseColor.B);

        penCopy.Width = thickness;
        penCopy.Color = color;

        gr.DrawPath(penCopy, path);
        
        alpha += delta;
      }

      gr.ResetTransform();
    }

    public static void DrawSmallShadow(this Graphics graphics, GraphicsPath path, Pen pen)
    {
      DrawSmallShadow(graphics, path, pen, Color.FromArgb(50, Color.Black));
    }

    public static void DrawSmallShadow(this Graphics graphics, GraphicsPath path, Pen pen, Color shadowColor)
    {
      using (Pen shadowPen = (Pen)pen.Clone())
      {
        shadowPen.Color = shadowColor;
        graphics.TranslateTransform(1, 1);
        graphics.DrawPath(shadowPen, path);
        graphics.ResetTransform();  
      }
    }
  }
}
